package first1

import scala.reflect.ClassTag

/**
  * description
  *
  * @author Llx
  * @version v1.0.0
  * @since 2018/10/8
  */

class ViewTest {

  /**
    * 3, View Bounds,可以进行某种神秘的转换，把你的类型可以在没有知觉的情况下转换成为目标类型，其实你可以认为 View Bounds是
    *
    * 上边界和下边界的加强补充版本，例如在SparkContext这个Spark的核心类中有T <% Writable方式的代码，这个代码所表达的是
    *
    * T必须是Writable类型的，但是T有没有直接继承自Writable接口，此时就需要通过“implicit”的方式来实现这个功能；
    *
    * 主方法：方法名[T <% String]
    * @param x
    * @tparam T
    */
  def f1[T <% String](x:T)={
   println( x+x)
  }


}

object ViewTest extends App{

  /**
    * 隐士转换函数：把 变量 1 转换成String类型(或者String的子类)，继续执行f1的方法
    * @param x
    * @return
    */
  implicit def int2String(x:Int):String={
    x.toString
  }
  private val test = new ViewTest()
  test.f1(1)


  /**
    * 隐士转换类 ：把 1 转换成ca类，调用add1的方法
    * @param a
    */
  implicit class Ca(a:Int){
    def add1(x:Int):Int={
      x+a
    }
  }
  1.add1(2)

  /**
    * 泛型函数  接受参数类型必须是：   [T:ClassTag]---->表示，泛型T必须是ClassTag类型，已定义的class的类型
    *                             构造Array是，里面存储的必须是class
    *     传入参数为 （泛型类型 传入多个参数）：  T*
    * @param e
    * @tparam T
    * @return
    */
  def f1[T:ClassTag](e:T*)= Array[T](e:_*)

   val ints = f1( ViewTest, ViewTest)
   println(ints)


  def f11[T](e:T)= {
    println(e.toString)
  }
  f11(1111)

}
